// 大体思路总结： 首先将问题进行拆分，将三数问题 转化成 俩数问题 即 nums[L] + nums[R] + nums[i] 与 0 的关系（因为nums[i]已固定）
//   通过for 循环进行遍历，即固定第一个数，然后就是俩个数和固定数的大小，后用双指针解决。
//   在将已经排序好的数组，根据双指针来确保三数相加逼近于0， 对于小于 0  移动左指针， 对于大于 0 移动右指针

// 去重思路总结： 首先对于遍历循环的第一个数i， 确保 nums[i] != nums[i-1]
//                其次对于 nums[L] + nums[R] + nums[i] == 0 的需要进行去重判断，判断和 遍历i 的去重差不多
//                比价 nums[start] == nums[start+1]  和 nums[end] == nums[end-1] 

var threeSum = function(nums) {
    let ans = [];
    const len = nums.length;
    if(nums == null || len < 3) return ans;
    nums.sort((a, b) => a - b); // 排序
    for (let i = 0; i < len ; i++) {
        if(nums[i] > 0) break; // 如果当前数字大于0，则三数之和一定大于0，所以结束循环
        if(i > 0 && nums[i] == nums[i-1]) continue; // 去重
        let L = i+1;
        let R = len-1;
        while(L < R){
            const sum = nums[i] + nums[L] + nums[R];
            if(sum == 0){
                ans.push([nums[i],nums[L],nums[R]]);
                while (L<R && nums[L] == nums[L+1]) L++; // 去重
                while (L<R && nums[R] == nums[R-1]) R--; // 去重
                L++;
                R--;
            }
            else if (sum < 0) L++;
            else if (sum > 0) R--;
        }
    }        
    return ans;
};


console.log(threeSum( [-1,0,1,2,-1,-4]));